package com.limpoxe.baidumapsdk;
import android.app.Application;
import android.content.ComponentName;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.InstrumentationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller;
import android.content.pm.PackageManager;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import java.lang.reflect.Field;
import java.util.List;
/**
* Created by cailiming on 16/12/30.
*/
public class FakeUtil {
/**
* 需要fakeContext并不是因为插件取不到自己的meta-data,
* 而是因为针对需要appkey的sdk插件,需要同时正确的取到下面3个值,
* 1、packageName
* 2、meta-data
* 3、signatures
*
* 默认情况是:
* 1、当packageName是宿主的时候,meta-data和signatures都会取到宿主的值
* 2、当packageName是插件的时候,meta-data和signatures都会取到插件的值
*
* 然而针对需要appkey的sdk插件来说,一般情况是这样:
* 1、packageName需要是宿主,因为appkey是注册的宿主的appkey
* 2、meta-data需要是插件,因为meta-data是放在插件的manifeat文件中
* 3、signatures需要是宿主,因为appkey是注册的宿主的signatures
* 因此需要fackeContext来实现这种组合
*
* 但是,如果注册appkey的时候,就直接使用了插件的packageName、meta-data、signatures
* 则无需使用fakeContext,直接使用插件的Application即可。
*
*/
public static Context fakeContext(final Application application) {
Application fakeForSdk = new Application() {
@Override
public String getPackageName() {
Context context = getBaseContext();
while (context instanceof ContextWrapper) {
context = ((ContextWrapper) context).getBaseContext();
}
//返回宿主packageName
return context.getPackageName();
}
@Override
public PackageManager getPackageManager() {
final PackageManager pm = super.getPackageManager();
return new PackageManager() {
@Override
public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException {
PackageInfo packageInfo = pm.getPackageInfo(packageName, flags);
if ((flags & PackageManager.GET_SIGNATURES) != 0 ) {
//返回宿主签名
packageInfo.signatures = pm.getPackageInfo(getPackageName(), flags).signatures;
}
return packageInfo;
}
@Override
public ApplicationInfo getApplicationInfo(String packageName, int flags) throws NameNotFoundException {
ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName, flags);
if ((flags & PackageManager.GET_META_DATA) != 0 ) {
Context context = getBaseContext();
while (context instanceof ContextWrapper) {
context = ((ContextWrapper) context).getBaseContext();
}
//返回宿主meta
applicationInfo.metaData = context.getApplicationInfo().metaData;
}
return applicationInfo;
}
@Override
public ActivityInfo getActivityInfo(ComponentName component, int flags) throws NameNotFoundException {
return pm.getActivityInfo(component, flags);
}
@Override
public ActivityInfo getReceiverInfo(ComponentName component, int flags) throws NameNotFoundException {
return pm.getReceiverInfo(component, flags);
}
@Override
public ServiceInfo getServiceInfo(ComponentName component, int flags) throws NameNotFoundException {
return pm.getServiceInfo(component, flags);
}
@Override
public ProviderInfo getProviderInfo(ComponentName component, int flags) throws NameNotFoundException {
return pm.getProviderInfo(component, flags);
}
@Override
public List<PackageInfo> getInstalledPackages(int flags) {
return pm.getInstalledPackages(flags);
}
@Override
public int checkSignatures(String pkg1, String pkg2) {
return pm.checkSignatures(pkg1, pkg2);
}
@Override
public int checkSignatures(int uid1, int uid2) {
return pm.checkSignatures(uid1, uid2);
}
@Override
public List<ResolveInfo> queryBroadcastReceivers(Intent intent, int flags) {
return pm.queryBroadcastReceivers(intent, flags);
}
//methods belows is not need, remain empty impl
@Override
public String[] currentToCanonicalPackageNames(String[] names) {
return new String[0];
}
@Override
public String[] canonicalToCurrentPackageNames(String[] names) {
return new String[0];
}
@Override
public Intent getLaunchIntentForPackage(String packageName) {
return null;
}
@Override
public Intent getLeanbackLaunchIntentForPackage(String packageName) {
return null;
}
@Override
public int[] getPackageGids(String packageName) throws NameNotFoundException {
return new int[0];
}
//@Override //android-N
public int[] getPackageGids(String packageName, int flags) throws NameNotFoundException {
return new int[0];
}
@Override
public PermissionInfo getPermissionInfo(String name, int flags) throws NameNotFoundException {
return null;
}
@Override
public List<PermissionInfo> queryPermissionsByGroup(String group, int flags) throws NameNotFoundException {
return null;
}
@Override
public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) throws NameNotFoundException {
return null;
}
@Override
public List<PermissionGroupInfo> getAllPermissionGroups(int flags) {
return null;
}
@Override
public List<PackageInfo> getPackagesHoldingPermissions(String[] permissions, int flags) {
return null;
}
@Override
public int checkPermission(String permName, String pkgName) {
return 0;
}
@Override
public boolean isPermissionRevokedByPolicy(String permName, String pkgName) {
return false;
}
@Override
public boolean addPermission(PermissionInfo info) {
return false;
}
@Override
public boolean addPermissionAsync(PermissionInfo info) {
return false;
}
@Override
public void removePermission(String name) {
}
@Nullable
@Override
public String[] getPackagesForUid(int uid) {
return new String[0];
}
@Nullable
@Override
public String getNameForUid(int uid) {
return null;
}
@Override
public List<ApplicationInfo> getInstalledApplications(int flags) {
return null;
}
@Override
public String[] getSystemSharedLibraryNames() {
return new String[0];
}
@Override
public FeatureInfo[] getSystemAvailableFeatures() {
return new FeatureInfo[0];
}
@Override
public boolean hasSystemFeature(String name) {
return false;
}
@Override
public ResolveInfo resolveActivity(Intent intent, int flags) {
return null;
}
@Override
public List<ResolveInfo> queryIntentActivities(Intent intent, int flags) {
return null;
}
@Override
public List<ResolveInfo> queryIntentActivityOptions(ComponentName caller, Intent[] specifics, Intent intent, int flags) {
return null;
}
@Override
public ResolveInfo resolveService(Intent intent, int flags) {
return null;
}
@Override
public List<ResolveInfo> queryIntentServices(Intent intent, int flags) {
return null;
}
@Override
public List<ResolveInfo> queryIntentContentProviders(Intent intent, int flags) {
return null;
}
@Override
public ProviderInfo resolveContentProvider(String name, int flags) {
return null;
}
@Override
public List<ProviderInfo> queryContentProviders(String processName, int uid, int flags) {
return null;
}
@Override
public InstrumentationInfo getInstrumentationInfo(ComponentName className, int flags) throws NameNotFoundException {
return null;
}
@Override
public List<InstrumentationInfo> queryInstrumentation(String targetPackage, int flags) {
return null;
}
@Override
public Drawable getDrawable(String packageName, int resid, ApplicationInfo appInfo) {
return null;
}
@Override
public Drawable getActivityIcon(ComponentName activityName) throws NameNotFoundException {
return null;
}
@Override
public Drawable getActivityIcon(Intent intent) throws NameNotFoundException {
return null;
}
@Override
public Drawable getActivityBanner(ComponentName activityName) throws NameNotFoundException {
return null;
}
@Override
public Drawable getActivityBanner(Intent intent) throws NameNotFoundException {
return null;
}
@Override
public Drawable getDefaultActivityIcon() {
return null;
}
@Override
public Drawable getApplicationIcon(ApplicationInfo info) {
return null;
}
@Override
public Drawable getApplicationIcon(String packageName) throws NameNotFoundException {
return null;
}
@Override
public Drawable getApplicationBanner(ApplicationInfo info) {
return null;
}
@Override
public Drawable getApplicationBanner(String packageName) throws NameNotFoundException {
return null;
}
@Override
public Drawable getActivityLogo(ComponentName activityName) throws NameNotFoundException {
return null;
}
@Override
public Drawable getActivityLogo(Intent intent) throws NameNotFoundException {
return null;
}
@Override
public Drawable getApplicationLogo(ApplicationInfo info) {
return null;
}
@Override
public Drawable getApplicationLogo(String packageName) throws NameNotFoundException {
return null;
}
@Override
public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) {
return null;
}
@Override
public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user, Rect badgeLocation, int badgeDensity) {
return null;
}
@Override
public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) {
return null;
}
@Override
public CharSequence getText(String packageName, int resid, ApplicationInfo appInfo) {
return null;
}
@Override
public XmlResourceParser getXml(String packageName, int resid, ApplicationInfo appInfo) {
return null;
}
@Override
public CharSequence getApplicationLabel(ApplicationInfo info) {
return null;
}
@Override
public Resources getResourcesForActivity(ComponentName activityName) throws NameNotFoundException {
return null;
}
@Override
public Resources getResourcesForApplication(ApplicationInfo app) throws NameNotFoundException {
return null;
}
@Override
public Resources getResourcesForApplication(String appPackageName) throws NameNotFoundException {
return null;
}
@Override
public void verifyPendingInstall(int id, int verificationCode) {
}
@Override
public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay) {
}
@Override
public void setInstallerPackageName(String targetPackage, String installerPackageName) {
}
@Override
public String getInstallerPackageName(String packageName) {
return null;
}
@Override
public void addPackageToPreferred(String packageName) {
}
@Override
public void removePackageFromPreferred(String packageName) {
}
@Override
public List<PackageInfo> getPreferredPackages(int flags) {
return null;
}
@Override
public void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity) {
}
@Override
public void clearPackagePreferredActivities(String packageName) {
}
@Override
public int getPreferredActivities(List<IntentFilter> outFilters, List<ComponentName> outActivities, String packageName) {
return 0;
}
@Override
public void setComponentEnabledSetting(ComponentName componentName, int newState, int flags) {
}
@Override
public int getComponentEnabledSetting(ComponentName componentName) {
return 0;
}
@Override
public void setApplicationEnabledSetting(String packageName, int newState, int flags) {
}
@Override
public int getApplicationEnabledSetting(String packageName) {
return 0;
}
@Override
public boolean isSafeMode() {
return false;
}
@NonNull
@Override
public PackageInstaller getPackageInstaller() {
return null;
}
//@Override //android-N
public boolean hasSystemFeature(String name,int flag) {
return false;
}
//@Override //android-N
public int getPackageUid(String name,int flag) {
return 0;
}
};
}
};
try {
Field base = ContextWrapper.class.getDeclaredField("mBase");
base.setAccessible(true);
Context c = (Context)base.get(application);
base.set(fakeForSdk, c);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return fakeForSdk;
}
}